package com.boot.mgt.service.impl

import com.boot.core.define.SESSION_KEY
import com.boot.core.result.ResultEnum
import com.boot.core.result.ResultTo
import com.boot.mgt.dao.mysql.TaPoliceMapper
import com.boot.mgt.dao.mysql.TaSessionMapper
import com.boot.mgt.model.TaPolice
import com.boot.mgt.model.TaSession
import com.boot.mgt.service.LoginService
import com.boot.mgt.service.TaPoliceService
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.security.MessageDigest
import java.util.*
import java.util.Random


/**
 * @author rankai
 * createTime 2018-01-2018/1/9 11:12
 */
@Service
class LoginServiceImpl : LoginService {

    @Autowired
    lateinit var sessionMapper: TaSessionMapper

    @Autowired
    private lateinit var taPoliceService: TaPoliceService

    override fun login(police_number: String, password: String, login_type: Int): ResultTo {
        val taPolice = taPoliceService.searchPoliceById(police_number);
        if (taPolice == null) {
            ResultTo(ResultEnum.USERNAME_ERROR)
        }
        taPolice.let {
            return if (verify(password, it["encrypted_password"] as String)) {
                if ((it["group_id"] as Long?) == 5L || (it["empower"] as String?) == "false") {
                    return ResultTo(ResultEnum.ILLEGAL_OPERATION, "您不能登录此APP")
                }
                val taSession = TaSession()
                with(taSession) {
                    policeNumber = it["user_name"] as String
                    type = login_type
                    sessionMapper.delete(taSession)
                    val buildSalt = UUID.randomUUID().toString()
                    sessionKey = buildSalt
                    sessionMapper.insertSelective(taSession)
                    val taPolice = TaPolice()
                    taPolice.policeNumber = it["user_name"] as String?
                    taPolice.name = it["full_name"] as String?
                    taPolice.xqdw = it["region_id"] as String?

                    ResultTo(ResultEnum.SUCCESS)
                            .setData(SESSION_KEY, buildSalt)
                            .setData("police", taPolice)
                            .setData("ver", "1.0.0") //成功
                }
            } else {
                ResultTo(ResultEnum.PASSWORD_ERROR) //密码错误
            }
        }
    }

    override fun logout(session_key: String) {
        val taSession = TaSession()
        taSession.sessionKey = session_key
        sessionMapper.delete(taSession)
    }


    companion object {

        private val log: Logger = LoggerFactory.getLogger(this::class.java)

        fun generate(password: String?): String? {
            var password = password
            val r = Random()
            val sb = java.lang.StringBuilder(16)
            sb.append(r.nextInt(99999999)).append(r.nextInt(99999999))
            val len = sb.length
            if (len < 16) {
                for (i in 0 until 16 - len) {
                    sb.append("0")
                }
            }
            val salt = sb.toString()
            password = md5Hex(password + salt)
            val cs = CharArray(48)
            var i = 0
            while (i < 48) {
                cs[i] = password!![i / 3 * 2]
                val c = salt[i / 3]
                cs[i + 1] = c
                cs[i + 2] = password[i / 3 * 2 + 1]
                i += 3
            }
            return String(cs)
        }

        /**
         * 校验密码是否正确
         */
        fun verify(password: String, md5: String): Boolean {
            val cs1 = CharArray(32)
            val cs2 = CharArray(16)
            var i = 0
            while (i < 48) {
                cs1[i / 3 * 2] = md5[i]
                cs1[i / 3 * 2 + 1] = md5[i + 2]
                cs2[i / 3] = md5[i + 1]
                i += 3
            }
            val salt = String(cs2)
            return md5Hex(password + salt) == String(cs1)
        }

        /**
         * 获取十六进制字符串形式的MD5摘要
         */
        fun md5Hex(src: String): String? {
            return try {
                val md5 = MessageDigest.getInstance("MD5")
                val bs: ByteArray = md5.digest(src.toByteArray())
                byteToHex(bs)
            } catch (e: Exception) {
                return null
            }
        }

        /**
         * byte数组转hex
         * @param bytes
         * @return
         */
        fun byteToHex(bytes: ByteArray): String? {
            var strHex = ""
            val sb = StringBuilder("")
            for (n in bytes.indices) {
                strHex = Integer.toHexString(bytes[n].toInt() and 0xFF)
                sb.append(if (strHex.length == 1) "0" + strHex else strHex) // 每个字节由两个字符表示，位数不够，高位补0
            }
            return sb.toString().trim()
        }
    }
}
